﻿using System;
using System.Globalization;
using T.FAS.Runtime.DataAccess.Common;
using T.FAS.Runtime.DataAccess.Engine.ValidateChecker.Entity;

namespace T.FAS.Runtime.DataAccess.Engine
{
    /// <summary>
    /// Decimal类型校验
    /// </summary>
    public class DecimalValidateFactory : CommonFactory
    {
        public override IColumnValidater GetDataTypeValidater()
        {
            return new DecimalDataTypeValidater();
        }

        public override IColumnValidater GetPrecisionValidater()
        {
            return new DecimalPrecisionValidater();
        }

        public override IColumnValidater GetLengthValidater()
        {
            return new DecimalLengthValidater();
        }
    }

    public class DecimalDataTypeValidater : IColumnDataTypeValidater
    {
        public ValidateCheckItem Validate(ValidateCheckItem item)
        {
            if (item.Result.IsStop)
                return item;
            //数据类型验证
            var inputVal = item.InputValue;
            if (inputVal is decimal decimalVal)
            {
                item.ConvertValue = decimalVal;
            }
            else if (inputVal is double doubleVal)
            {
                //double类型直接转换为decimal，不再转为string后用decimal.TryParse方法
                item.ConvertValue = Convert.ToDecimal(doubleVal);
            }
            else if (inputVal is float floatVal)
            {
                //float类型直接转换为decimal，不再转为string后用decimal.TryParse方法
                item.ConvertValue = Convert.ToDecimal(floatVal);
            }
            else if (decimal.TryParse(inputVal.ToString(), AbstractDataTypeTool.NumberStyle_Default, AbstractDataTypeTool.Culture_Const, out decimal value))
            {
                item.ConvertValue = value;
            }
            else
            {
                item.Result.Flag = false;
                item.Result.IsStop = true;
                item.Result.Msg.Append(string.Format(ValidateConst.DataTypeErrorTemp, item.CheckElement.Name, inputVal, item.CheckElement.DataType));
            }
            return item;
        }
    }

    public class DecimalLengthValidater : IColumnLengthValidater
    {
        public ValidateCheckItem Validate(ValidateCheckItem item)
        {
            //DecimalSpecialValidater.Validate(item);
            if (item.Result.IsStop)
                return item;
            /*
             * Decimal数据长度验证: Decimal(P,D), 
             * P表示数字的有效位数, D表示小数点后的位数
             * 长度验证时需要排除小数点(.), 减号(-)
             */
            //指定ToString()时为不变的语言区域，保证 12.34不会toString为12,34。
            CultureInfo culture = AbstractDataTypeTool.Culture_Const;
            decimal value = (decimal)item.ConvertValue;
            int entireLength = value.ToString(culture).Replace("-", "").Replace(".", "").Length;
            if (entireLength > item.CheckElement.Length)
            {
                item.Result.Flag = false;
                item.Result.Msg.Append(string.Format(ValidateConst.LengthErrorTemp,
                    item.CheckElement.Name,
                    item.CheckElement.DataType,
                    item.InputValue,
                    entireLength,
                    item.CheckElement.Length));
            }

            int integerPartLength = value.ToString(culture).Replace("-", "").Split('.')[0].Length;
            int integerPartLengthStd = item.CheckElement.Length - item.CheckElement.Precision;
            if (integerPartLength > integerPartLengthStd)
            {
                item.Result.Flag = false;
                item.Result.Msg.Append(string.Format("字段:{0},类型:{1},输入值:{2},整数部分长度:{3},大于最大长度{4}" + ExceptionManage.LineFeedSymbol,
                    item.CheckElement.Name,
                    item.CheckElement.DataType,
                    item.InputValue,
                    integerPartLength,
                    integerPartLengthStd));
            }
            return item;
        }
    }

    public class DecimalPrecisionValidater : IColumnPrecisionValidater
    {
        public ValidateCheckItem Validate(ValidateCheckItem item)
        {
            //DecimalSpecialValidater.Validate(item);
            if (item.Result.IsStop)
                return item;
            //数据精度验证
            var inputVal = item.InputValue.ToString();
            int index = inputVal.IndexOf(".");
            if (index != -1)
            {
                string fractionalPart = inputVal.Substring(index + 1);
                if (fractionalPart.Length > item.CheckElement.Precision)
                {
                    item.Result.Flag = false;
                    item.Result.Msg.Append(string.Format(ValidateConst.PresicionErrorTemp,
                        item.CheckElement.Name,
                        item.CheckElement.DataType,
                        inputVal,
                        fractionalPart.Length,
                        item.CheckElement.Precision));
                }
            }
            return item;
        }
    }

    public class DecimalSpecialValidater
    {
        public const short DECIMAL_MAX_PRECISION = 38;
        public static ValidateCheckItem Validate(ValidateCheckItem item)
        {
            if (item.Result.IsStop)
                return item;
            //Decimal长度精度综合Check
            int length = item.ConvertValue.ToString().Replace("-", "").Replace(".", "").Length;
            if (length > DECIMAL_MAX_PRECISION)
            {
                item.Result.Flag = false;
                item.Result.IsStop = true;
                item.Result.Msg.Append(
                    string.Format("字段:{0},类型:{1},输入值:{2},长度精度之和{3}大于最大长度{4}" + ExceptionManage.LineFeedSymbol,
                        item.CheckElement.Name,
                        item.CheckElement.DataType,
                        item.InputValue,
                        length,
                        DECIMAL_MAX_PRECISION));
            }
            return item;
        }
    }
}